<?php
declare(strict_types=1);

namespace App\Service;

use App\Model\Dao\MchInfoDao;
use App\Model\Dao\RiskRuleCollectionDao;
use App\Model\Dao\RiskRuleWhitetextDao;
use App\Model\Enum\RiskRuleCollectionTypeEnum;
use App\Model\Enum\RiskRuleMchRefTypeEnum;
use App\Utils\CustomUtils;
use App\Utils\StringUtils;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use App\Model\Dao\RiskRuleMchRefDao;
use Hyperf\Utils\Arr;

class RiskRuleMchRefService {

    /**
     * @Inject()
     * @var RiskRuleMchRefDao
     */
    private $RiskRuleMchRefDao;

    /**
     * @Inject()
     * @var RiskRuleWhitetextDao
     */
    private $RiskRuleWhitetextDao;

    /**
     * @Inject()
     * @var RiskRuleCollectionDao
     */
    private $RiskRuleCollectionDao;

    /**
     * @Inject()
     * @var MchInfoDao
     */
    private $MchInfoDao;

    /**
     * @Inject()
     * @var SyncService
     */
    private $SyncService;


    /**
     * 商户风控/类型下拉框
     *
     * @param $params
     *
     * @return array
     */
    public function typeOptions ($params) {
        $data = RiskRuleMchRefTypeEnum::born()->getOptions();
        return CustomUtils::buildSuccess($data);
    }

    /**
     * 商户风控/设置关联
     *
     * @param $params
     *
     * @return array
     * @throws \Exception
     */
    public function setBind ($params) {

        $mchIdList    = Arr::get($params, 'mchIdList', null);
        $mchNo        = $params['mchNo'];
        $collectionId = $params['collectionId'];
        $type         = $params['type'];

        // 检查商户信息
        $this->_verifyMchNoOrFail($mchNo, $mchIdList);

        // 检查风控信息
        if (!empty($collectionId)) {
            $this->_verifyCollectionIdOrFail($collectionId, $type);
        }

        Db::beginTransaction();

        try {
            // 解除旧关联, 设置新关联
            $this->RiskRuleMchRefDao->delWhere([
                'mchNo' => $mchNo,
                'type'  => $type,
            ]);

            if (!empty($collectionId)) {
                $this->RiskRuleMchRefDao->insert([
                    'id'           => StringUtils::uuidV4(),
                    'collectionId' => $collectionId,
                    'mchNo'        => $mchNo,
                    'type'         => $type,
                    'createTime'   => time(),
                    'createBy'     => $params['createBy'],
                    'updateBy'     => $params['createBy'],
                ]);
            }

        } catch (\Throwable $e) {
            Db::rollBack();
            throw $e;
        }

        Db::commit();

        // 刷新风控缓存
        switch ($type) {
            case RiskRuleMchRefTypeEnum::WHITE:
                $this->SyncService->syncRiskRuleWhiteTextMchRef($mchNo);
                break;
            case RiskRuleMchRefTypeEnum::NORMAL:
                $this->SyncService->syncRiskRuleMchRef($mchNo);
                break;
            case RiskRuleMchRefTypeEnum::SUSPICIOUS:
                $this->SyncService->syncRiskRuleSuspiciousMchRef($mchNo);
                break;
        }

        $data = [];
        return CustomUtils::buildSuccess($data);
    }

    /**
     * 判断传入风控集合ID是否正确
     *
     * @param $collectionId
     * @param $type
     *
     * @throws \Exception
     */
    protected function _verifyCollectionIdOrFail ($collectionId, $type) {

        $collection = null;

        switch ($type) {
            case RiskRuleMchRefTypeEnum::WHITE:
                $collection = $this->RiskRuleWhitetextDao->get($collectionId);
                break;
            case RiskRuleMchRefTypeEnum::NORMAL:
                $collection = $this->RiskRuleCollectionDao->getWhere([
                    'id'   => $collectionId,
                    'type' => RiskRuleCollectionTypeEnum::MERCHANT,
                ]);
                break;
            case RiskRuleMchRefTypeEnum::SUSPICIOUS:
                $collection = $this->RiskRuleCollectionDao->getWhere([
                    'id'   => $collectionId,
                    'type' => RiskRuleCollectionTypeEnum::SUSPICIOUS,
                ]);
                break;
        }

        if (!$collection) {
            throw new \Exception('未找到对应风控规则集合');
        }
    }

    /**
     * 判断传入mchNo是否正确
     *
     * @param      $mchNo
     * @param null $mchIdList
     *
     * @throws \Exception
     */
    protected function _verifyMchNoOrFail ($mchNo, $mchIdList = null) {

        $mch = $this->MchInfoDao->getWhere(['mchNo' => $mchNo]);

        if (!$mch) {
            throw new \Exception('未找到商户信息');
        }

        if (!is_null($mchIdList)) {
            if (!in_array($mch['id'], $mchIdList)) {
                throw new \Exception('没有此商户的权限');
            }
        }
    }

    public function list ($params) {

        $page  = Arr::pull($params, 'page', null);
        $limit = Arr::pull($params, 'limit', null);

        $total = $this->RiskRuleMchRefDao->getCount($params);
        $list  = $this->RiskRuleMchRefDao->getList($params, $page, $limit);

        foreach ($list as $k => $v) {
            $v['createTime'] = CustomUtils::xzxGetDateTime($v['createTime']);
            $v['strStatus']  = $this->RiskRuleMchRefDao->strStatus($v['status']);
            $v['strType']    = $this->RiskRuleMchRefDao->strType($v['type']);
            $list[$k]        = $v;
        }

        $data = [
            'total' => $total,
            'list'  => $list,
        ];

        return CustomUtils::buildSuccess($data);
    }

    public function info ($params) {
        $page  = 1;
        $limit = 1;

        $list = $this->RiskRuleMchRefDao->getList($params, $page, $limit);
        $list = CustomUtils::formatCreateTime($list);

        $info = reset($list);


        return CustomUtils::buildSuccess($info);
    }

}
